﻿namespace nhappend.Data
{
    using System;
    using System.Collections.Generic;
    using NHibernate;
    using NHibernate.Expression;

    public class LogMessageRepository : ILogMessageRepository
    {
        protected readonly ISessionBuilder _sessionBuilder;

        public LogMessageRepository() : this(new SessionBuilder())
        {
        }

        public LogMessageRepository(ISessionBuilder sessionFactory)
        {
            _sessionBuilder = sessionFactory;
        }

        protected ISession GetSession()
        {
            ISession session = _sessionBuilder.GetSession();
            return session;
        }

        public void Create(LogMessage entity)
        {
            using (ISession session = GetSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Save(entity);
                    session.Flush();

                    transaction.Commit();
                }
            }
        }

        public LogMessage Retrieve(Guid entityId)
        {
            LogMessage entity;

            using (ISession session = GetSession())
            {
                ICriteria criteria = session.CreateCriteria(typeof(LogMessage));
                criteria.Add(Expression.Eq("Id", entityId));

                entity = criteria.UniqueResult<LogMessage>();
            }

            return entity;
        }

        public IList<LogMessage> RetrieveAll(OrderBy order)
        {
            IList<LogMessage> itemList;

            using (ISession session = GetSession())
            {
                Order sortOrder = GetSortOrder(order);

                ICriteria targetObjects = session.CreateCriteria(typeof(LogMessage));
                targetObjects = targetObjects.AddOrder(sortOrder);

                itemList = targetObjects.List<LogMessage>();
            }

            return itemList;
        }

        private static Order GetSortOrder(OrderBy order)
        {
            return (order.Order == SortOrder.Ascending)
                       ? Order.Asc(order.PropertyName)
                       : Order.Desc(order.PropertyName);
        }

        public IList<LogMessage> RetrieveAll()
        {
            return RetrieveAll(new OrderBy
                                   {
                                       Order = SortOrder.Ascending,
                                       PropertyName = "Id"
                                   });
        }

        public void Update(LogMessage entity)
        {
            using (ISession session = GetSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Update(entity);
                    session.Flush();

                    transaction.Commit();
                }
            }
        }

        public void Delete(LogMessage entity)
        {
            using (ISession session = GetSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Delete(entity);
                    session.Flush();

                    transaction.Commit();
                }
            }
        }

        public void DeleteById(Guid entityId)
        {
            var entity = Retrieve(entityId);
            if (entity == null) return;

            Delete(entity);
        }

        public void DeleteAll()
        {
            var list = RetrieveAll();
            foreach (var entity in list)
            {
                Delete(entity);
            }
        }
    }
}